﻿package com.views.structure {
	import com.View;
	import com.utils.oObject;
	import com.views.IView;
	import com.views.Shortcut;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	import flash.utils.setTimeout;

	/**
	 *
	 * @author Administrator
	 */
	/**
	 *
	 * @author Administrator
	 */
	public class Popup extends Base {

		private var _superViews:Array;
		private var _coexistViews:Array;
		private var _exclusiveViews:Array;
		private var _inTownViews:Array;
		private var _freeViews:Array;
		/**
		 *
		 * @default
		 */
		public var structure:Structure;
		private var _view:View;
		private var _supers:Dictionary;
		private var _views:Dictionary;
		private var _frees:Dictionary;
		private var _supersList:Array;
		private var _viewsList:Array; // 已存在的VIEW
		private var _timerOut:Timer;
		private var _hasFade:Boolean = false;
		private var _fadeOutList:Dictionary;
		private var _shape:Sprite;
		private var _alphp:Number = 0;
		private var _currentAddedView:IView;
		private var _processList:Dictionary;
		private var _focusView:IView;

		/**
		 *
		 * @param _arg1
		 */
		public function Popup(_arg1:View):void {
			this._supers = new Dictionary();
			this._views = new Dictionary();
			this._frees = new Dictionary();
			this._supersList = [];
			this._viewsList = [];
			this._fadeOutList = new Dictionary();
			this._processList = new Dictionary();
			super();
			this._view = _arg1;
			this._superViews = this._view.superViews;
			this._coexistViews = this._view.coexistViews;
			this._exclusiveViews = this._view.exclusiveViews;
			this._inTownViews = this._view.inTownViews;
			this._freeViews = this._view.freeViews;
			this._view.addToFrameProcessList(this.toString(), this.process);
		}

		/**
		 *
		 * @param view
		 * @param content
		 */
		public function addView(view:IView, content:Sprite):void {
			if (this.hasViewIncluded(view, this._freeViews)) {
				this.removeFadeOutList(view);
				this._frees[view] = content;
				this.addChildWithFade(view, content);
				return;
			}
			;
			if (this.hasViewIncluded(view, this._superViews)) {
				this.closeAll();
				this.removeFadeOutList(view);
				this._supers[view] = content;
				this.addChildWithFade(view, content);
				return;
			}
			;
			var _needCloseView:Array = this.getCoexistViews(view);
			if (_needCloseView.length > 0) {
				_needCloseView = _needCloseView[0];
			}
			;
			_needCloseView.push(view);
			this.closeExclude(_needCloseView);
			this.removeFadeOutList(view);
			this._views[view] = content;
			this.addChildWithFade(view, content);
			this.setfocusView(view);
			content.mouseChildren = true;
			content.mouseEnabled = true;
			if (content.width < Structure.stageWidth) {
				content.x = Math.floor(((Structure.stageWidth - content.width) / 2));
				content.y = Math.floor(((Structure.stageHeight - content.height) / 2));
			}

			if (this._viewsList.indexOf(view) == -1) {
				this._viewsList.push(view);
			}

			this._currentAddedView = view;
			this.reposition();
			setTimeout(this.reposition, 10);
		}

		private function addChildWithFade(_addedView:IView, _addedPanel:Sprite):void {
			var bm:Bitmap;
			var handle:Function;
			var timer:Timer;
			var view:IView = _addedView;
			var panel:Sprite = _addedPanel;
			addChild(panel);
		}

		/**
		 *
		 * @param _targetView
		 */
		public function closeView(_targetView:IView):void {
			var _local2:Object;
			var _isFreeView:Sprite;
			var _local4:Sprite;
			if (this.hasViewIncluded(_targetView, this._freeViews)) {
				_isFreeView = this._frees[_targetView];
				if (_isFreeView) {
					this.startFadeOut(_targetView, true);
					this._view.cancelCenter(_targetView.sign); // 取消重新定位(resize)
					delete this._frees[_targetView];
					removeChild(_isFreeView);
					Shortcut.removeView(_targetView);
				}
				return;
			}
			if (this.hasViewIncluded(_targetView, this._superViews)) {
				_local4 = this._supers[_targetView];
				if (_local4) {
					this._view.cancelCenter(_targetView.sign);
					delete this._supers[_targetView];
					removeChild(_local4);
					Shortcut.removeView(_targetView);
				}
				;
				return;
			}
			if ((this._views[_targetView] is Sprite)) {
				this._views[_targetView].mouseChildren = false;
				this._views[_targetView].mouseEnabled = false;
				this.closeView0(_targetView, true);
			}
			this.setfocusView(null);
			for (_local2 in this._views) {
				if (this.focusView == null) {
					this.setfocusView((_local2 as IView));
					break;
				}
			}
			setTimeout(this.reposition, 100);
		}

		private function closeView0(_closeKey:IView, _open:Boolean):void {
			this._view.cancelCenter(_closeKey.sign);
			this.startFadeOut(_closeKey);
			this.removeView(_closeKey);
			if (false == _open) {
				_closeKey.close();
			}
			;
			var _local3:int = this._viewsList.length;
			var _local4:int;
			while (_local4 < _local3) {
				if (_closeKey == this._viewsList[_local4]) {
					this._viewsList.splice(_local4, 1);
					break;
				}
				;
				_local4++;
			}
			;
			Shortcut.removeView(_closeKey);
		}

		private function removeView(_arg1:IView):void {
			if (((this._views[_arg1]) && (this._views[_arg1].parent))) {
				removeChild(this._views[_arg1]);
			}
			;
			delete this._views[_arg1];
		}

		private function closeExclude(_arg1:Array):void {
			var _local2:Array = oObject.getKeys(this._views);
			var _local3:int;
			while (_local3 < _local2.length) {
				if (_arg1.indexOf(_local2[_local3]) == -1) {
					this.closeView0((_local2[_local3] as IView), false);
				}
				;
				_local3++;
			}
			;
		}

		override public function closeAll():void {
			var _local3:IView;
			var _local1:Array = oObject.getKeys(this._views);
			var _local2:int;
			while (_local2 < _local1.length) {
				_local3 = _local1[_local2];
				this._view.cancelCenter(_local3.sign);
				this.startFadeOut(_local3);
				this.closeView0(_local3, false);
				_local2++;
			}
			;
			this.setfocusView(null);
		}

		/**
		 *
		 * @param _arg1
		 * @return
		 */
		public function hasView(_arg1:IView):Boolean {
			return (((((!(!(this._views[_arg1]))) || (!(!(this._supers[_arg1]))))) || (!(!(this._frees[_arg1])))));
		}

		/**
		 *
		 * @param _arg1
		 */
		public function updateFocusView(_focus:Sprite):void {
			var _viewKey:*;
			for (_viewKey in this._views) {
				if (this._views[_viewKey] == _focus) {
					if (this.focusView != _viewKey) {
						this.setfocusView((_viewKey as IView));
					}
					break;
				}
			}
		}

		/**
		 *
		 * @param _arg1
		 * @return
		 */
		public function getRelatedView(_arg1:DisplayObject):IView {
			var obj:DisplayObject = _arg1;
			var handler:Function = function(_arg1:Dictionary):IView {
				var _local2:*;
				for (_local2 in _arg1) {
					if (_arg1[_local2].contains(obj)) {
						return (_local2);
					}
					;
				}
				;
				return (null);
			};
			return (((((handler(this._views)) || (handler(this._supers)))) || (handler(this._frees))));
		}

		private function getCoexistViews(_arg1:IView):Array {
			var _local5:Array;
			var _local6:Array;
			var _local7:Object;
			var _local2:Array = [];
			var _local3:int = this._coexistViews.length;
			var _local4:int;
			while (_local4 < _local3) {
				_local5 = this._coexistViews[_local4];
				if (this.hasViewIncluded(_arg1, _local5) != false) {
					_local6 = [];
					for (_local7 in this._views) {
						if (this.hasViewIncluded((_local7 as IView), _local5) == true) {
							_local6.push(_local7);
						}
					}
				}
				_local4++;
			}
			return (_local2);
		}

		private function hasViewIncluded(_arg1:IView, _arg2:Array):Boolean {
			var _local3:int = ((_arg2) ? _arg2.length : 0);
			var _local4:int;
			while (_local4 < _local3) {
				if ((_arg1 is _arg2[_local4])) {
					return (true);
				}
				;
				_local4++;
			}
			;
			return (false);
		}

		/**
		 *
		 * @param _arg1
		 * @return
		 */
		public function allowToOpen(_arg1:IView):Boolean {
			var _local2:Object;
			for (_local2 in this._views) {
				if (this.hasExclusive((_local2 as IView), _arg1)) {
					(_local2 as IView).inStageWithTip;
					return (false);
				}
				;
			}
			;
			for (_local2 in this._supers) {
				if (this.hasExclusive((_local2 as IView), _arg1)) {
					(_local2 as IView).inStageWithTip;
					return (false);
				}
				;
			}
			;
			if (this.hasViewIncluded(_arg1, this._freeViews)) {
				return (true);
			}
			;
			return (true);
		}

		private function hasExclusive(_arg1:IView, _arg2:IView):Boolean {
			var _local5:Object;
			var _local6:Array;
			var _local7:Array;
			var _local3:int = this._exclusiveViews.length;
			var _local4:int;
			while (_local4 < _local3) {
				_local5 = this._exclusiveViews[_local4];
				if ((_arg1 is _local5["master"])) {
					_local6 = _local5["black"];
					_local7 = _local5["white"];
					if ((((_local6.length == 0)) && ((_local7.length == 0)))) {
						return (true);
					}
					;
					if (_local7.length > 0) {
						if (this.hasViewIncluded(_arg2, _local7)) {
							return (false);
						}
						;
						return (true);
					}
					;
					if (_local6.length > 0) {
						if (this.hasViewIncluded(_arg2, _local6)) {
							return (true);
						}
						;
						return (false);
					}
					;
				}
				;
				_local4++;
			}
			;
			return (false);
		}

		/**
		 *
		 * @param _arg1
		 * @return
		 */
		public function hasExclusiveView(_arg1:Class):int {
			var _local4:Object;
			var _local2:int = this._exclusiveViews.length;
			var _local3:int;
			while (_local3 < _local2) {
				_local4 = this._exclusiveViews[_local3];
				if (_local4["master"] == _arg1) {
					return (_local3);
				}
				;
				_local3++;
			}
			;
			return (-1);
		}

		/**
		 *
		 * @param _arg1
		 */
		public function addExclusiveView(_arg1:Class):void {
			if (this.hasExclusiveView(_arg1) > -1) {
				return;
			}
			;
			this._exclusiveViews.push({master: _arg1, black: [], white: []});
		}

		/**
		 *
		 * @param _arg1
		 */
		public function removeExclusiveView(_arg1:Class):void {
			var _local2:int = this.hasExclusiveView(_arg1);
			if (_local2 > -1) {
				this._exclusiveViews.splice(_local2, 1);
			}
			;
		}

		private function removeFadeOutList(_arg1:IView):void {
			if (this._fadeOutList[_arg1]) {
				removeChild(this._fadeOutList[_arg1]);
				delete this._fadeOutList[_arg1];
			}
		}

		private function startFadeOut(_fadeOutView:IView, _notNormal:Boolean = false):void {
			var _local4:BitmapData;
			var _local5:Bitmap;
			if (this._timerOut == null) {
				this._timerOut = new Timer(10);
				this._timerOut.addEventListener(TimerEvent.TIMER, this.onFadeOut);
			}
			var _fadeOutTarget:Sprite = _notNormal == false ? this._views[_fadeOutView] : (this._supers[_fadeOutView] || this._frees[_fadeOutView]);
			if (((((_fadeOutTarget) && ((_fadeOutTarget.width > 0)))) && ((_fadeOutTarget.height > 0)))) {
				_local4 = new BitmapData(_fadeOutTarget.width, _fadeOutTarget.height, true, 0);
				_local4.draw(_fadeOutTarget);
				_local5 = new Bitmap(_local4);
				_local5.x = _fadeOutTarget.x;
				_local5.y = _fadeOutTarget.y;
				addChildAt(_local5, getChildIndex(_fadeOutTarget));
				this.removeFadeOutList(_fadeOutView);
				this._fadeOutList[_fadeOutView] = _local5;
			}
			this._hasFade = true;
			this._timerOut.start();
		}

		private function onFadeOut(_evt:TimerEvent):void {
			var _key:Object;
			var _target:Bitmap;
			var _local2:int;
			for (_key in this._fadeOutList) {
				_target = this._fadeOutList[_key];
				if (_target.alpha > 0) {
					_target.alpha = (_target.alpha - 0.08);
					_local2++;
				} else {
					delete this._fadeOutList[_key];
					removeChild(_target);
				}
			}
			if (_local2 == 0) {
				this._hasFade = false;
				this._timerOut.stop();
			}
		}

		/**
		 *
		 * @param _arg1
		 * @param _arg2
		 */
		public function addMask(_arg1:Boolean = false, _arg2:Number = 0):void {
			if (this._shape == null) {
				this._shape = new Sprite();
			}
			;
			this._alphp = _arg2;
			if (_arg1) {
				addChild(this._shape);
			} else {
				addChildAt(this._shape, 0);
			}
			;
			this.reposition();
		}

		/**
		 *
		 */
		public function removeMask():void {
			if (((this._shape) && (this._shape.parent))) {
				removeChild(this._shape);
			}
			;
		}

		/**
		 *
		 */
		public function reposition():void {
			var view:IView;
			var content:Sprite;
			var toX:int;
			var toY:int;
			var _greaterThanStage:Boolean;
			var _startX:Number;
			var _local11:Boolean;
			var _local12:Boolean;
			var _local13:Boolean;
			if (this._shape != null && this._shape.parent != null) {
				this._shape.graphics.clear();
				this._shape.graphics.beginFill(0, this._alphp);
				this._shape.graphics.drawRect(-50, -50, 1350, 750);
				this._shape.graphics.endFill();
			}
			;
			var _viewSpace:int = 10; // 视图间隔
			var _addedViewTotalWidth:Number = 0;
			var _viewSize:int = this._viewsList.length;
			var _lastViewIndex:int = (_viewSize - 1);
			while (_lastViewIndex > -1) {
				view = this._viewsList[_lastViewIndex];
				;
				content = this._views[view];
				if (content) {
					_addedViewTotalWidth = _addedViewTotalWidth + content.width + (_lastViewIndex > 0 ? _viewSpace : 0);
				}
				;
				_lastViewIndex--;
			}
			;
			if (_viewSize == 1) { // 只有一个,显示在屏幕正中央
				content = this._views[this._viewsList[0]];
				toX = Math.floor((Structure.stageWidth - content.width) / 2);
				toY = Math.floor((Structure.stageHeight - content.height) / 2);
				this.moveTo(this._viewsList[0], content, toX, toY);
			} else {
				if (_viewSize > 1) { // 多个
					_greaterThanStage = (_addedViewTotalWidth > Structure.stageWidth);
					_startX = (Structure.stageWidth - _addedViewTotalWidth) / 2;
					_local11 = true; // (this._currentAddedView is PackView) && this.hasViewInstance(RoleMsgView, this._viewsList) && this.hasViewInstance(PackView, this._viewsList);
					_local12 = true; //(this._currentAddedView is RoleMsgView) && this.hasViewInstance(RoleMsgView, this._viewsList) && this.hasViewInstance(PackView, this._viewsList);
					var _local14:Boolean = true; //(this._currentAddedView is PackView) && this.hasViewInstance(WarehouseView, this._viewsList) && this.hasViewInstance(PackView, this._viewsList);
					_local13 = (_local11 || (!_local11 && !_local12));
					_lastViewIndex = _local13 ? 0 : (_viewSize - 1);
					_viewSpace = _local14 ? 50 : 10;
					while (_local13 ? (_lastViewIndex < _viewSize) : (_lastViewIndex > -1)) {
						content = this._views[this._viewsList[_lastViewIndex]];
						if (content) {
							toX = Math.floor(_greaterThanStage ? ((Structure.stageWidth - content.width) / 2) : _startX);
							toY = Math.floor((Structure.stageHeight - content.height) / 2);
							this.moveTo(this._viewsList[_lastViewIndex], content, toX, toY);
							_startX = _startX + content.width + _viewSpace;
						}
						if (_local13) {
							_lastViewIndex++;
						} else {
							_lastViewIndex--;
						}
					}
				}
			}
		}

		/**
		 * 查看指定列表,是否存在指定类型
		 *
		 * @param _viewCls 指定类型
		 *
		 * @param _instanceList 指定列表
		 *
		 * @return 是否存在
		 *
		 */
		private function hasViewInstance(_viewCls:Class, _instanceList:Array):Boolean {
			var _insSize:uint = _instanceList.length;
			var _index:uint;
			while (_index < _insSize) {
				if ((_instanceList[_index] is _viewCls)) {
					return true;
				}
				_index++;
			}
			return false;
		}

		/**
		 * 移动视图
		 *
		 * @param _moveView 需要移动的视图
		 *
		 * @param _target 移动目标
		 *
		 * @param _toX 目标X
		 *
		 * @param _toY 目标Y
		 *
		 */
		private function moveTo(_moveView:IView, _target:Sprite, _toX:Number, _toY:Number):void {
			var _deltaX:Number = (_toX - _target.x);
			var _deltaY:Number = (_toY - _target.y);
			var _timeline:int = 6;
			var _stepX:Number = (_deltaX / _timeline);
			var _stepY:Number = (_deltaY / _timeline);
			this._processList[_moveView] = {panel: _target, x: _target.x, y: _target.y, dx: _stepX, dy: _stepY, i: 0, n: _timeline};
		}

		private function process():void {
			var _viewInstance:IView;
			var _moveDataObject:Object;
			var _keys:Array = oObject.getKeys(this._processList);
			var _keySize:int = _keys.length;
			var _keyIndex:int;
			while (_keyIndex < _keySize) {
				_viewInstance = _keys[_keyIndex];
				_moveDataObject = this._processList[_viewInstance];
				if (_moveDataObject.panel.parent && _moveDataObject.i < _moveDataObject.n) {
					_moveDataObject.panel.x = (_moveDataObject.panel.x + _moveDataObject.dx);
					_moveDataObject.panel.y = (_moveDataObject.panel.y + _moveDataObject.dy);
					_moveDataObject.i++;
				} else {
					delete this._processList[_viewInstance];
				}
				_keyIndex++;
			}
		}

		private function setfocusView(_viewTarget:IView):void {
			this._focusView = _viewTarget;
			Shortcut.focusView = _viewTarget;
		}

		/**
		 *
		 * @return
		 */
		public function get views():Dictionary {
			return (this._views);
		}

		/**
		 *
		 * @return
		 */
		public function get focusView():IView {
			return (this._focusView);
		}
	}
}
